import { Dialog, Space, Toast } from "antd-mobile";
import { colorToRGB565, rgbToHex } from "@/utils/color";

/**
 * Components
 */
import Canvas from "@/components/canvas";
import classNames from "classnames";
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useSetState } from "ahooks";

/**
 * Types
 */
type Step = {
  index: number;
  from: string;
  to: string;
};

type State = {
  colors: string[];
  index: number;
  color: string;
  type: "pencil" | "eraser";
  undo: Step[][];
  redo: Step[][];
  temp: Step[];
};

/**
 * Constants
 */
const colors = [
  "#4E4646",
  "#FFFFFF",
  "#E50113",
  "#EA6100",
  "#F39800",
  "#FEF100",
  "#8FC320",
  "#009A44",
  "#00A1E8",
  "#0169B8",
  "#1D208A",
  "#930683",
];

const PageCreate: React.FC = () => {
  /**
   * Hooks
   */
  const navigate = useNavigate();

  /**
   * States
   */
  const [state, setState] = useSetState<State>({
    colors: [],
    index: -1,
    color: "#4E4646",
    type: "pencil",
    undo: [],
    redo: [],
    temp: [],
  });

  /**
   * Events
   */
  const onUndoClick = () => {
    const step = state.undo.pop();

    if (step) {
      const colors = state.colors || [];

      for (const item of step) {
        colors[item.index] = rgbToHex(item.from);
      }

      setState({
        colors,
        undo: state.undo,
        redo: [...state.redo, step],
      });
    }
  };

  const onRedoClick = () => {
    const step = state.redo.pop();

    if (step) {
      const colors = state.colors || [];

      for (const item of step) {
        colors[item.index] = item.to;
      }

      setState({
        colors,
        undo: [...state.undo, step],
        redo: state.redo,
      });
    }
  };

  const onTouch = (e: React.TouchEvent) => {
    // 结束
    if (e.type === "touchend") {
      if (!state.temp.length) {
        return;
      }

      setState({
        undo: [...state.undo, state.temp],
        redo: [],
        temp: [],
      });

      return;
    }

    // 开始 || 移动
    const touch = e.touches[0];
    const target = document.elementFromPoint(
      touch.clientX,
      touch.clientY
    ) as HTMLDivElement;

    if (target && target.classList.contains("jj-canvas-point")) {
      const index = Number(target.getAttribute("data-index"));
      const color = state.type === "pencil" ? state.color : "#FFFFFF";

      if (state.colors[index] === color) {
        return;
      }

      const colors = state.colors || [];

      colors[index] = color;

      setState({
        colors,
        temp: [
          ...state.temp,
          {
            index,
            from: target.style.backgroundColor,
            to: color,
          },
        ],
      });
    }
  };

  const onSaveClick = () => {
    JeeWeb.getUserProfile((user) => {
      JeeWeb.get("index", ({ result }) => {
        const list = result || [];

        const item = {
          colors: state.colors,
          id: user.result.id,
          name: user.result.name,
          time: Date.now(),
        };

        if (state.index > -1) {
          list[state.index] = item;
        } else {
          list.push(item);
        }

        JeeWeb.set("index", list, () => {
          navigate("/");
        });
      });
    });
  };

  const onShowClick = () => {
    JeeWeb.requestFileUploadToken(({ result }) => {
      fetch(import.meta.env.VITE_API + "/im/cup/bin", {
        body: JSON.stringify({
          token: result.token,
          data: Array.from(
            { length: 512 },
            (_, k) => "0x" + colorToRGB565(state.colors[k] || "#FFFFFF")
          ),
        }),
        headers: {
          "Content-Type": "application/json",
        },
        method: "post",
      })
        .then((r) => r.json())
        .then((r) => {
          device
            .setDevMessage({
              value: {
                method: "showRGBBitmap",
                params: {
                  content: {
                    url: r.result.binFileUrl,
                    size: r.result.size,
                    type: "application/bin",
                  },
                },
              },
            })
            .then(() => {
              Toast.show("已推送至水杯");
            })
            .catch(() => {
              Toast.show("推送失败");
            });
        });
    });
  };

  /**
   * Effects
   */
  useEffect(() => {
    JeeWeb &&
      JeeWeb.get("current", ({ result }) => {
        setState({
          colors: result?.item.colors || [],
          index: result?.index > -1 ? result.index : -1,
        });
      });
  }, []);

  return (
    <div
      className="jj-page-create"
      onTouchStart={onTouch}
      onTouchMove={onTouch}
      onTouchEnd={onTouch}
    >
      <div className="jj-main">
        <div className="jj-action-left">
          <div className="jj-action">
            <div
              className="jj-action-work"
              onClick={() => {
                if (state.undo.length || state.redo.length) {
                  Dialog.confirm({
                    title: "尚未保存",
                    content: "确认返回作品页？",
                    onConfirm: () => {
                      navigate("/");
                    },
                  });
                } else {
                  navigate("/");
                }
              }}
            >
              作品
            </div>
          </div>

          <div style={{ flex: 1 }} />

          <div className="jj-action">
            <div
              className={classNames("jj-action-delete", {
                "jj-action-delete-active":
                  state.colors.length || state.undo.length || state.redo.length,
              })}
              onClick={() => {
                Dialog.confirm({
                  title: "删除项目",
                  content: "确认是否删除涂鸦作品",
                  onConfirm: () => {
                    setState({
                      colors: [],
                      undo: [],
                      redo: [],
                    });
                  },
                });
              }}
            />
          </div>

          <div style={{ flex: "0 0 16px" }} />

          <div className="jj-action">
            <div
              className={classNames("jj-action-undo", {
                "jj-action-undo-active": state.undo.length,
              })}
              onClick={onUndoClick}
            />

            <div className="jj-action-divider" />
            <div
              className={classNames("jj-action-redo", {
                "jj-action-redo-active": state.redo.length,
              })}
              onClick={onRedoClick}
            />
          </div>
        </div>

        <div className="jj-canvas-wrap">
          <div className="jj-canvas-absolute">
            <Canvas colors={state.colors} style={{ gap: 1 }} />
          </div>
        </div>

        <div className="jj-action-right">
          <div style={{ flex: 1 }} />

          <div className="jj-action">
            <div
              className={classNames("jj-action-pencil", {
                "jj-action-pencil-active": state.type === "pencil",
              })}
              onClick={() => {
                setState({ type: "pencil" });
              }}
            />

            <div className="jj-action-divider" />

            <div
              className={classNames("jj-action-eraser", {
                "jj-action-eraser-active": state.type === "eraser",
              })}
              onClick={() => {
                setState({ type: "eraser" });
              }}
            />
          </div>
        </div>
      </div>

      <div className="jj-footer">
        <div style={{ flex: 1, overflowX: "auto" }}>
          <Space style={{ "--gap": "10px" }}>
            {colors.map((color, index) => (
              <div
                className={classNames("jj-color", {
                  "jj-color-active": state.color === color,
                })}
                key={index}
                style={{
                  backgroundColor: color,
                }}
                onClick={() => setState({ color })}
              />
            ))}
          </Space>
        </div>

        <Space style={{ "--gap": "10px", marginLeft: "16px" }}>
          <div className="jj-btn jj-btn-save" onClick={onSaveClick} />

          <div className="jj-btn jj-btn-show" onClick={onShowClick} />
        </Space>
      </div>
    </div>
  );
};

export default PageCreate;
